package com.beanverify.inter.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beanverify.annotations.Date;
import com.beanverify.annotations.Email;
import com.beanverify.annotations.Ip;
import com.beanverify.annotations.Null;
import com.beanverify.annotations.Number;
import com.beanverify.exceptions.UnKnownVerifyException;
import com.beanverify.exceptions.UnSupportedParamTypeException;
import com.beanverify.inter.AnnotationVerifier;
import com.beanverify.inter.BeanChecker;
import com.beanverify.inter.verifier.impl.VerifyDate;
import com.beanverify.inter.verifier.impl.VerifyEmail;
import com.beanverify.inter.verifier.impl.VerifyIp;
import com.beanverify.inter.verifier.impl.VerifyNull;
import com.beanverify.inter.verifier.impl.VerifyNumber;

public class MyBeanChecker implements BeanChecker{
	private static Logger log = LoggerFactory.getLogger(MyBeanChecker.class);

	private MyAnnotationBox annotationBox = new MyAnnotationBox();
	public static MyBeanChecker checker = null;

	public synchronized static void init(){
		if (null == checker){
			checker = new MyBeanChecker();
			MyBeanChecker.addNewVerifyAnno(Null.class, VerifyNull.class);
			MyBeanChecker.addNewVerifyAnno(Number.class, VerifyNumber.class);
			MyBeanChecker.addNewVerifyAnno(Ip.class, VerifyIp.class);
			MyBeanChecker.addNewVerifyAnno(Email.class, VerifyEmail.class);
			MyBeanChecker.addNewVerifyAnno(Date.class, VerifyDate.class);
		}
	}

	public static boolean doCheck(Object bean){
		return checker.doCheckBean(bean);
	}
	
	public static void addNewVerifyAnno(Class<? extends Annotation> annoclazz, Class<? extends AnnotationVerifier> annoVerifyClazz) {
		init();
		checker.getAnnotationBox().addNewAnno(annoclazz, annoVerifyClazz);
	}

	public boolean doCheckBean(Object bean) {
		Field[] fields = bean.getClass().getDeclaredFields();
		try {
			for (Field f : fields) {
				f.setAccessible(true);
				if (!doCheckParm(f.get(bean), f.getName(), f.getDeclaredAnnotations())){
					return false;
				}
			}
		} catch (IllegalArgumentException e) {
			log.error("BeanVerifyError",e);
		} catch (IllegalAccessException e) {
			log.error("BeanVerifyError",e);
		}
		return true;
	}

	private boolean doCheckParm(Object param, String paramName, Annotation[] annotations){
		for (Annotation annotation : annotations) {
			AnnotationVerifier verifyFeild = annotationBox.getAnno(annotation.annotationType());
			if (verifyFeild!=null){
				try {
					if (false == verifyFeild.doVerify(param, paramName, annotation)){
						return false;
					} else continue;
				} catch (UnSupportedParamTypeException e) {
					log.error("类型检查异常",e);
					return false;
				} catch (ClassCastException e) {
					log.error("类型检查异常",e);
					return false;
				} catch (UnKnownVerifyException e) {
					log.error("未知检查异常",e);
					return false;
				} catch (Exception e) {
					log.error("未知检查异常",e);
					return false;
				}
			} else continue;
		}
		return true;
	}

	public MyAnnotationBox getAnnotationBox() {
		return annotationBox;
	}
}
